package main

import (
	"fmt"
	"sync"
	"time"
)

// 读写锁
/**
	sync.RWMutex 读写锁类型
	提供的函数：
		写锁：加锁/解锁
			func (*RWMutex) Lock()
			func (RWmutex) UnLock()
		读锁：加锁/解锁
			func (*RWMutex) RLock()
			func (RWmutex) RUnLock()

	写解锁会试图唤醒所有因欲进行的读锁定而堵塞的 goroutine
	读解锁只会试图唤醒一个因欲进行写锁定而被堵塞的 goroutine


	// 通过 sync.RWMutex 的指针函数获取锁本身(读锁)

	var rwm sync.RWMutex
	// 获取读写锁本身
	locker := rwm.RLocker()
	// 读加锁
	locker.Lock()
	// 读解锁
	locker.Unlock()

**/

func main() {
	var rwm sync.RWMutex

	// 只针对读锁
	// locker := rwm.RLocker()
	// locker.Lock()
	// locker.Unlock()

	for i := 0; i < 3; i++ {
		go func(i int) {
			fmt.Printf("准备开始读取。。。，尝试获取读锁定！[%d]\n", i)
			rwm.RLock()
			fmt.Printf("获取到读锁定，开始读取。。。[%d]\n", i)
			fmt.Printf("正在读取中，[%d]\n", i)
			time.Sleep(time.Second * 2)
			fmt.Printf("读取完成，开始释放读锁！[%d]\n", i)
			rwm.RUnlock()
			fmt.Printf("读锁释放完成！[%d]\n", i)
		}(i)
	}

	time.Sleep(time.Microsecond * 1000)
	fmt.Printf("主函数准备尝试获取写锁定![%s]\n", "main")
	rwm.Lock()
	fmt.Printf("主函数获取到写锁定![%s]\n", "main")
}
